/**
 * ResultDeserializer.java
 * Create on 2012-2-24下午04:49:11
 * Copyright (c) 2012 by e_trans.
 */
package com.yc.jpyy.base.util;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;

/**
 * @author Ivan
 * @version 1.0
 */
public class ResultDeserializer implements JsonDeserializer<Result>{
	
 public Result deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException{
	
  	if (json.isJsonNull()){
  		return null;
  	} 
  	else if (json.isJsonPrimitive()){
  		return null;
  	}
  	else if (json.isJsonArray()){
  		return null;
  	}
  	else{
  		return  handleResult(json, context);
  	}
 }

 
 
 private Result handleResult(JsonElement json,JsonDeserializationContext context){
	
	
	Result  result = new Result();
	
	for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet())
	{
	
	 String key = entry.getKey();
	 JsonElement ele = (JsonElement) entry.getValue();
	 if("data".equals(key))
	 {
		
		if(ele.isJsonArray())
		{
		 result.setData(handleArray(ele, context));
		}
		else if(ele.isJsonObject())
		{
		 result.setData(handleObject(ele,context));
		}
		
	 }
	 else if ("code".equals(key))
	 {
		result.setCode(ele.getAsInt());
	 }
	 
	 else if ("msg".equals(key))
	 {
		result.setMsg(ele.getAsString());
	 }
	 
	}
	return result;
 }
 
 
 
 
 private Map<String, Object> handleObject(JsonElement json,JsonDeserializationContext context)
	{
		Map<String, Object> map = new HashMap<String, Object>();
		
		for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet())
		{
			JsonElement ele = (JsonElement) entry.getValue();
			if (ele.isJsonNull()) 
			{
				map.put(entry.getKey(), null);
			} 
			else if (ele.isJsonPrimitive()) 
			{
				map.put(entry.getKey(), handlePrimitive(ele));
			}
			else if (ele.isJsonArray()) 
			{
				map.put(entry.getKey(), handleArray(ele, context));
			}
			else
			{
				map.put(entry.getKey(), handleObject(ele, context));
			}
		}
		return map;
	}
 
 
/**
 * 解析基本数据
 * @param jsonEle
 * @return
 */
	private Object handlePrimitive(JsonElement jsonEle) 
	{
		JsonPrimitive json = jsonEle.getAsJsonPrimitive();
		
		if (json.isBoolean())
			return json.getAsBoolean();
		else if (json.isString()) 
		{
			return json.getAsString();
		} 
		else 
		{
			BigDecimal bigDec = json.getAsBigDecimal();
			try
			{
				bigDec.toBigIntegerExact();
				try 
				{
					return bigDec.intValueExact();
				} 
				catch (ArithmeticException e) 
				{
				}
				return bigDec.longValue();
			} 
			catch (ArithmeticException e) 
			{
			}
			return bigDec.doubleValue();
		}
	}

	/**
	 * 解析List
	 * @param jsonEle
	 * @param context
	 * @return
	 */
	private Object handleArray(JsonElement jsonEle,	JsonDeserializationContext context) 
	{
		JsonArray json = jsonEle.getAsJsonArray();
		int listSize = json.size();
		
		List<Object> list = new ArrayList<Object>(listSize);
		for (int i = 0; i < listSize; i++)
		{
			list.add(deserialize(json.get(i), context));
		}
		return list;
	}
	/**
	 * 解析 HashMap
	 * @param json
	 * @param context
	 * @return
	 * @throws JsonParseException
	 */
	private Object deserialize(JsonElement json,JsonDeserializationContext context) throws JsonParseException 
	{
		if (json.isJsonNull()) 
		{
			return null;
		} 
		else if (json.isJsonPrimitive()) 
		{
			return handlePrimitive(json);
		} 
		else if (json.isJsonArray()) 
		{
			return handleArray(json, context);
		}
		else 
		{
			return (HashMap<String, Object>) handleObject(json, context);
		}
	}

 
}
